package com.tomorrow.runner.activity.main;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.v4.widget.DrawerLayout;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.amap.api.location.AMapLocation;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.services.weather.LocalWeatherForecastResult;
import com.amap.api.services.weather.LocalWeatherLive;
import com.amap.api.services.weather.LocalWeatherLiveResult;
import com.amap.api.services.weather.WeatherSearch;
import com.amap.api.services.weather.WeatherSearchQuery;
import com.tomorrow.runner.R;
import com.tomorrow.runner.activity.SportResultActivity;
import com.tomorrow.runner.activity.basic.BasicActivity;
import com.tomorrow.runner.activity.history.HistoryActivity;
import com.tomorrow.runner.activity.report.ReportActivity;
import com.tomorrow.runner.activity.user.UserInfoActivity;
import com.tomorrow.runner.data.bean.UserBean;
import com.tomorrow.runner.data.model.ActivityDataModel;
import com.tomorrow.runner.data.model.ActivityModel;
import com.tomorrow.runner.extend.heartdetect.HeartRateActivity;
import com.tomorrow.runner.map.LatLngPoint;
import com.tomorrow.runner.map.MapFragment;
import com.tomorrow.runner.service.PushUpDetector;
import com.tomorrow.runner.service.StepsDetector;
import com.tomorrow.runner.test.DBUtil;
import com.tomorrow.runner.util.CaloriesUtil;
import com.tomorrow.runner.util.Define;
import com.tomorrow.runner.util.LatLngUtil;
import com.tomorrow.runner.util.SensorUtil;
import com.tomorrow.runner.util.TimeUitl;
import com.tomorrow.runner.util.WeatherUtil;

import cn.sucun.android.log.Log;

public class HomeActivity extends BasicActivity implements
         DrawerLayout.DrawerListener, AdapterView.OnItemClickListener, View.OnClickListener, MapFragment.LocationListener {

    private static final String TAG = "HomeActivity";

    public enum SportType{
        Run,
        PushUp
    }
    private DrawerLayout mHomeDrawer;
    private ListView mFuncList;
    private ImageView mUserIcon;
    private TextView mUserInfo;
    private Intent[] mFuncIntents;
    private MapFragment mMapFragment;
    private Button mBtnStartActivity;
    private Button mBtnLock;
    private TextView mCityName;
    private ImageView mWeatherState;
    private TextView mWeatherDetail;
    private StepsDetector mStepsDetector;
    private PushUpDetector mPushUpDetector;
    private int stepCount = 0;
    private MainInfoPanel mainInfoPanel;
    private SportType mCurrentSportType = SportType.Run;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        mStepsDetector = new StepsDetector(this,onStepDetectListener);
        SensorUtil.showSensorList(this);
        initUI();
        initGPS();
        DBUtil.showTable(this);
    }

    StepsDetector.OnStepDetectListener onStepDetectListener = new StepsDetector.OnStepDetectListener(){

        @Override
        public void onDetectOrientation(int orientation) {

        }

        @Override
        public void onDetect(StepsDetector detector, float threshold) {
            if (threshold == StepsDetector.DEFAULT_THRESHOLD){
                stepCount++;
            }
        }

        @Override
        public void onMissDetect(StepsDetector detector, float threshold) {

        }
    };



    private void initUI() {
        mainInfoPanel = new MainInfoPanel(this);
        mMapFragment = (MapFragment) getSupportFragmentManager().findFragmentById(R.id.map_area);
        mMapFragment.setLocationListener(this,MapFragment.FAST);
        mBtnStartActivity = (Button) findViewById(R.id.btn_start);
        mBtnStartActivity.setOnClickListener(this);
        mBtnLock = (Button) findViewById(R.id.btn_lock);
        mBtnLock.setOnClickListener(this);
        mCityName = (TextView) findViewById(R.id.city_name_label);
        mWeatherState = (ImageView) findViewById(R.id.weather_state_icon);
        mWeatherDetail = (TextView) findViewById(R.id.detail_label);
        initDrawer();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mMapFragment != null){
            mMapFragment.setUpMapIfNeeded(MapFragment.SetupModel.Location,null);
        }
    }

    private void initDrawer() {
        mHomeDrawer = (DrawerLayout) findViewById(R.id.home_drawer_layout);
        mHomeDrawer.addDrawerListener(this);
        mFuncList = (ListView) findViewById(R.id.left_func_list);

        mUserIcon = (ImageView) findViewById(R.id.user_icon);
        mUserInfo = (TextView) findViewById(R.id.user_name);

        mUserInfo.setText(getUserInfo()!= null ? getUserInfo().username : "");

        String[] labels = {getString(R.string.my_history),
                getString(R.string.my_report),
                getString(R.string.my_diy),
                getString(R.string.my_kit),
                getString(R.string.settings)};

        int[] imgIds = {R.mipmap.history,
                R.mipmap.report,
                R.mipmap.diy,
                R.mipmap.more,
                R.mipmap.set};

        mFuncIntents = new Intent[]{new Intent(this, HistoryActivity.class),
                new Intent(this, ReportActivity.class),
                null,
                new Intent(this, HeartRateActivity.class),
                null};

        DrawerListAdapter adapter = new DrawerListAdapter(this,labels,imgIds);
        mFuncList.setAdapter(adapter);
        mFuncList.setOnItemClickListener(this);

        mUserIcon.setOnClickListener(this);
    }


    @Override
    public void onDrawerSlide(View drawerView, float slideOffset) {

    }

    @Override
    public void onDrawerOpened(View drawerView) {

    }

    @Override
    public void onDrawerClosed(View drawerView) {
    }

    @Override
    public void onDrawerStateChanged(int newState) {

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Intent intent = mFuncIntents[position];
        if (intent != null){
            startActivity(intent);
            mHomeDrawer.closeDrawers();
        }
        else{
            showMsgToast("开发中");
        }
    }

    /**
     * 监听GPS
     */
    private void initGPS() {
        LocationManager locationManager = (LocationManager) this
                .getSystemService(Context.LOCATION_SERVICE);
        // 判断GPS模块是否开启，如果没有则开启

        if (!locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
            AlertDialog.Builder dialog = new AlertDialog.Builder(this );
            dialog.setMessage(R.string.gps_request);
            dialog.setPositiveButton(R.string.confirm,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int arg1) {
                            // 转到手机设置界面，用户设置GPS
                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                            startActivityForResult(intent, 0); // 设置完成后返回到原来的界面
                        }
                    });
            dialog.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int arg1) {
                    dialog.dismiss();
                }
            } );
            dialog.show();
        }
    }
    private boolean mIsStarted = false;
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.user_icon:
                Intent intent = new Intent(this, UserInfoActivity.class);
                startActivity(intent);
                break;
            case R.id.btn_start:
                if (mIsStarted){
                    mBtnLock.setVisibility(View.GONE);
                    mBtnStartActivity.setText(getText(R.string.start_running));
                    stopActivity();
                }else{
                    showActivityTypeSelectDialog();
                }
                break;
            case R.id.btn_lock:
                if (mBtnStartActivity.isEnabled()){
                    mBtnStartActivity.setEnabled(false);
                    mBtnLock.setText(getText(R.string.unlock));
                }
                else{
                    mBtnStartActivity.setEnabled(true);
                    mBtnLock.setText(getText(R.string.locked));
                }
                break;
        }
    }

    private void startActivity() {
        mBtnStartActivity.setEnabled(false);
        mBtnLock.setVisibility(View.VISIBLE);
        mBtnStartActivity.setText(getText(R.string.stop_running));
        mStepsDetector.addThreshold(1.2f);
        mStepsDetector.startDetect();
        stepCount = 0;
        mPreferences.edit().clear().apply();
        //记录开始时间
        mPreferences.edit().putLong(Define.KEY_START_TIME,System.currentTimeMillis()).apply();
        switch (mCurrentSportType){
            case Run:
                mPreferences.edit().putString(Define.KEY_POINTS,"").apply();
                playSound(R.raw.coming);
                break;
            case PushUp:
                pushUpCount = 0;
                mainInfoPanel.distanceLabel.setText(pushUpCount+" 个");
                if (mPushUpDetector == null){
                    mPushUpDetector = new PushUpDetector(this,mPushUpDetectListener);
                }
                mPushUpDetector.startDetect();
                if ( mMapFragment.getView() != null){
                    mMapFragment.getView().setVisibility(View.GONE);
                }
                findViewById(R.id.push_up_panel).setVisibility(View.VISIBLE);
                break;
        }
        mIsStarted = true;
    }

    private int pushUpCount = 0;
    PushUpDetector.OnPushUpDetectListener mPushUpDetectListener = new PushUpDetector.OnPushUpDetectListener() {
        @Override
        public void onPushUpDetect() {
            pushUpCount++;
            mainInfoPanel.distanceLabel.setText(pushUpCount+" 个");
        }
    };
    private void stopActivity() {
        mainInfoPanel.mainInfo.setText(TimeUitl.getTimeFormat(0));
        mainInfoPanel.distanceLabel.setText("0");
        mainInfoPanel.speedLabel.setText("0");
        mainInfoPanel.caloriesLabel.setText("0");
        mIsStarted = false;
        mStepsDetector.stopDetect();
        UserBean userBean = getUserInfo();
        if (userBean == null){
            return;
        }
        ContentValues values = new ContentValues();
        values.put(ActivityModel.START_TIME,mPreferences.getLong(Define.KEY_START_TIME,System.currentTimeMillis()));
        values.put(ActivityModel.END_TIME,System.currentTimeMillis());
        values.put(ActivityModel.WEATHER,mPreferences.getString(Define.KEY_WEATHER,WeatherUtil.SUNNY));
        values.put(ActivityModel.POSITION,mPreferences.getString(Define.KEY_POSITION,""));
        values.put(ActivityModel.OWNER, userBean.username);
        int type = ActivityModel.TYPE_RUN;
        switch (mCurrentSportType){
            case Run:
                type = ActivityModel.TYPE_RUN;
                break;
            case PushUp:
                type = ActivityModel.TYPE_PUSH_UP;
                break;
        }
        values.put(ActivityModel.ACTIVITY_TYPE,type);
        Uri uri = getContentResolver().insert(ActivityModel.getContentUri(), values);
//        Log.i(TAG,uri.toString());
        long id = ContentUris.parseId(uri);
        switch (mCurrentSportType){
            case Run:
                //point
                values.clear();
                values.put(ActivityDataModel.ACTIVITY_ID,id);
                values.put(ActivityDataModel.DATA_TYPE,ActivityDataModel.TYPE_POSITION_POINT);
                values.put(ActivityDataModel.PRIMARY_DATA,mPreferences.getString(Define.KEY_POINTS,""));
                getContentResolver().insert(ActivityDataModel.getContentUri(), values);
//                Log.i(TAG,"point="+mPreferences.getString(Define.KEY_POINTS,"")+"uri"+uri.toString());
                //steps
                values.clear();
                values.put(ActivityDataModel.ACTIVITY_ID,id);
                values.put(ActivityDataModel.DATA_TYPE,ActivityDataModel.TYPE_BASE_COUNT);
                values.put(ActivityDataModel.PRIMARY_DATA,""+stepCount);
                getContentResolver().insert(ActivityDataModel.getContentUri(), values);
//                Log.i(TAG,"steps="+stepCount+"uri"+uri.toString());

                //speed
                float speed = mPreferences.getFloat(Define.KEY_SPEED,0);
                values.clear();
                values.put(ActivityDataModel.ACTIVITY_ID,id);
                values.put(ActivityDataModel.DATA_TYPE,ActivityDataModel.TYPE_AVG_SPEED);
                values.put(ActivityDataModel.PRIMARY_DATA,""+speed);
                getContentResolver().insert(ActivityDataModel.getContentUri(), values);
//                Log.i(TAG,"speed="+speed+"uri"+uri.toString());
                //mile
                float mile = mPreferences.getFloat(Define.KEY_MILE,0);
                values.clear();
                values.put(ActivityDataModel.ACTIVITY_ID,id);
                values.put(ActivityDataModel.DATA_TYPE,ActivityDataModel.TYPE_MILE);
                values.put(ActivityDataModel.PRIMARY_DATA,""+mile);
                getContentResolver().insert(ActivityDataModel.getContentUri(), values);
//                Log.i(TAG,"mile="+mile+"uri"+uri.toString());
                //calories
                double calories = CaloriesUtil.getRunCalories(mile,userBean.weight);
                values.clear();
                values.put(ActivityDataModel.ACTIVITY_ID,id);
                values.put(ActivityDataModel.DATA_TYPE,ActivityDataModel.TYPE_CALORIE);
                values.put(ActivityDataModel.PRIMARY_DATA,""+calories);
                getContentResolver().insert(ActivityDataModel.getContentUri(), values);
//                Log.i(TAG,"calories="+calories+"uri"+uri.toString());
                break;
            case PushUp:
                //count
                int count = pushUpCount;
                values.clear();
                values.put(ActivityDataModel.ACTIVITY_ID,id);
                values.put(ActivityDataModel.DATA_TYPE,ActivityDataModel.TYPE_BASE_COUNT);
                values.put(ActivityDataModel.PRIMARY_DATA,""+count);
                getContentResolver().insert(ActivityDataModel.getContentUri(), values);
                //calories
                calories = CaloriesUtil.getRunCalories(count,userBean.weight);
                values.clear();
                values.put(ActivityDataModel.ACTIVITY_ID,id);
                values.put(ActivityDataModel.DATA_TYPE,ActivityDataModel.TYPE_CALORIE);
                values.put(ActivityDataModel.PRIMARY_DATA,""+calories);
                getContentResolver().insert(ActivityDataModel.getContentUri(), values);
                mPushUpDetector.stopDetect();
                if ( mMapFragment.getView() != null){
                    mMapFragment.getView().setVisibility(View.VISIBLE);
                }
                findViewById(R.id.push_up_panel).setVisibility(View.GONE);
                break;
        }
        Intent intent = new Intent(this, SportResultActivity.class);
        Bundle bundle = new Bundle();
        bundle.putInt(Define.KEY_ID, (int) id);
        bundle.putInt(Define.KEY_TYPE, type);
        intent.putExtras(bundle);
        startActivity(intent);
    }

    private void showActivityTypeSelectDialog() {
        final String[] types = {
                getString(R.string.type_run),
                getString(R.string.type_push_up),
            };
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getText(R.string.select_type));
        builder.setItems(types, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                showMsgToast(types[which]);
                switch (which){
                    case 0:
                        mCurrentSportType = SportType.Run;
                        break;
                    case 1:
                        mCurrentSportType = SportType.PushUp;
                        break;
                }
                startActivity();
            }
        });
        builder.show();
    }

    boolean exit = false;
    @Override
    public void onBackPressed() {
        if (exit){
            super.onBackPressed();
        }else{
            showMsgToast("再按一次返回键退出应用");
            exit = true;
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    exit = false;
                }
            },2000);
        }
    }
    private void initWeather(AMapLocation amapLocation){
        if(amapLocation == null){
            showMsgToast("无法获取当前位置信息");
            return;
        }
        mCityName.setText(amapLocation.getCity());
        WeatherSearchQuery query = new WeatherSearchQuery(amapLocation.getCity(), WeatherSearchQuery.WEATHER_TYPE_LIVE);//检索参数为城市和天气类型，实时天气为1、天气预报为2
        WeatherSearch weathersearch = new WeatherSearch(this);
        weathersearch.setOnWeatherSearchListener(mOnWeatherSearchListener);
        weathersearch.setQuery(query);
        weathersearch.searchWeatherAsyn(); //异步搜索
    }
    WeatherSearch.OnWeatherSearchListener mOnWeatherSearchListener = new WeatherSearch.OnWeatherSearchListener() {
        @Override
        public void onWeatherLiveSearched(LocalWeatherLiveResult localWeatherLiveResult, int i) {
            LocalWeatherLive result = localWeatherLiveResult.getLiveResult();

            String sb = "温度 " + result.getTemperature() + " " +
                    result.getWindDirection() + "风 " +
                    result.getWindPower() + "级 " +
                    "湿度 " + result.getHumidity();
            mWeatherDetail.setText(sb);
            mWeatherDetail.requestFocus();
            int resId = WeatherUtil.getWeatherIconId(result.getWeather());
            mWeatherState.setImageResource(resId);
            //记录天气
            mPreferences.edit().putString(Define.KEY_WEATHER,result.getWeather()).apply();
        }

        @Override
        public void onWeatherForecastSearched(LocalWeatherForecastResult localWeatherForecastResult, int i) {

        }
    };
    private long lastUpdateWeatherTime = 0;
    private long lastUpdateLocationTime = 0;
    @Override
    public void onLocationSuccess(AMapLocation amapLocation) {
//        Log.i(TAG,"onLocationSuccess");
        //跟新天气信息
        if (System.currentTimeMillis() - lastUpdateWeatherTime >= Define.ONE_HOUR / 2){
            lastUpdateWeatherTime = System.currentTimeMillis();
            initWeather(amapLocation);
        }
        if (mIsStarted){
            //记录地点
            mPreferences.edit().putString(Define.KEY_POSITION,amapLocation.getCity()).apply();
            //时间
            int duration = (int) (System.currentTimeMillis() -  mPreferences.getLong(Define.KEY_START_TIME,System.currentTimeMillis()));
            duration = duration/1000;
            mainInfoPanel.mainInfo.setText(TimeUitl.getTimeFormat(duration));
            if (mCurrentSportType == SportType.Run){
                //更新位置
                if (System.currentTimeMillis() - lastUpdateLocationTime >= 3*1000){
                    lastUpdateLocationTime = System.currentTimeMillis();
                    saveLocationPoint(amapLocation);
                }
            }
            else{
                float speed = pushUpCount / duration ;
                mainInfoPanel.speedLabel.setText(speed+" 个/秒");
                //计算消耗
                double calories = CaloriesUtil.getPushUpCalories(pushUpCount,getUserInfo().weight) / 1000;
                mainInfoPanel.caloriesLabel.setText(((int)calories)+" 千卡");
            }
        }else{
            mBtnStartActivity.setEnabled(true);
        }
    }
    private void saveLocationPoint(AMapLocation amapLocation) {
        String pointsText = mPreferences.getString(Define.KEY_POINTS,"{}");
        Log.i(TAG,"pointsText="+pointsText);
        JSONArray points = JSON.parseArray(pointsText);
        LatLngPoint point = new LatLngPoint(amapLocation.getLatitude(),amapLocation.getLongitude());
        if (points != null && points.size() > 0){
            LatLngPoint lastPoint = points.getObject(points.size()-1,LatLngPoint.class);
            Log.i(TAG,"lastPoint="+lastPoint.toString());
            //计算距离
            float distance = mPreferences.getFloat(Define.KEY_MILE,0);
            distance += LatLngUtil.distanceBetween(new LatLng(lastPoint.lat,lastPoint.lng),new LatLng(point.lat,point.lng));
            Log.i(TAG,"distance="+distance);
            if (distance == 0){
                if (stepCount > 0){
                    distance = stepCount * 0.5f;
                }
            }
            mainInfoPanel.distanceLabel.setText(((int)distance)+" 米");
            mPreferences.edit().putFloat(Define.KEY_MILE,distance).apply();
            long startTime = mPreferences.getLong(Define.KEY_START_TIME,System.currentTimeMillis());
            //计算速度
            if (System.currentTimeMillis() - startTime > 0){
                float speed = distance / ((System.currentTimeMillis() - startTime) / 1000.0f);
                mPreferences.edit().putFloat(Define.KEY_SPEED,speed).apply();
                Log.i(TAG,"speed="+speed);
                mainInfoPanel.speedLabel.setText(((int)speed)+" 米/秒");
            }
            //计算消耗
            double calories = CaloriesUtil.getRunCalories(distance,getUserInfo().weight) / 100;
            mainInfoPanel.caloriesLabel.setText(((int)calories)+" 千卡");
        }
        else{
            points = new JSONArray();
        }
        if (!points.contains(point)){
            points.add(point);
        }
        mPreferences.edit().putString(Define.KEY_POINTS,points.toJSONString()).apply();
        Log.i(TAG,"points="+points.toJSONString());
    }

    @Override
    public void onLocationLost(AMapLocation lastLocation) {
        mBtnStartActivity.setEnabled(false);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        mStepsDetector.stopDetect();
    }

    class MainInfoPanel{
        public TextView mainInfo;
        public TextView speedLabel;
        public TextView distanceLabel;
        public TextView caloriesLabel;
        public MainInfoPanel(Activity activity){
            mainInfo = (TextView) activity.findViewById(R.id.home_main_info);
            speedLabel = (TextView) activity.findViewById(R.id.txt_speed);
            distanceLabel = (TextView) activity.findViewById(R.id.txt_distance);
            caloriesLabel = (TextView) activity.findViewById(R.id.txt_calories);
        }
    }
}
